#include "MainWindow.h"

#include <QDateTime>
#include <QFileDialog>
#include <QMessageBox>
#include <QTimer>

#include "./Project/CommInputDialog.h"
#include "./Project/NewCollectChannelDialog.h"
#include "Project/NewProjectDialog.h"
#include "ProtocalInterface.h"
#include "SARibbonApplicationButton.h"
#include "SARibbonMenu.h"
#include "tool/DownLoadDialog.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow(QWidget* parent)
    : SARibbonMainWindow(parent)
    , mMenuApplicationBtn(nullptr)
    , m_menuProject(nullptr)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowIcon(QIcon(":/resource/MainIcon.png"));
    resize(1300, 810);

    m_projectAttribForm = new ProjectAttribForm();
    m_collectChannelForm = new CollectChannlForm();
    m_collectDeviceForm = new CollectDeivceForm();
    m_collectCountForm = new CollectChannelCountForm();
    m_updateChannelForm = new UpdateChannelForm();
    m_updateCountForm = new UpdateChannelCountForm();
    SARibbonBar* ribbon = ribbonBar();
    ribbon->setContentsMargins(1, 0, 1, 0);
    //系统菜单
    initApplicationMenu();
    //工程管理dock
    ui->dockWidget->setWindowTitle("工程管理");
    m_projectTreeWidget = new QProjectTreeWidget();
    ui->dockWidget->setWidget(m_projectTreeWidget);
    //工程菜单
    m_menuProject = new QMenu();
    initToolboorProject();
    //新建设备通道
    m_menuCollectChannel = new QMenu();
    QAction* actNewChannel = createAction("新建采集通道", ":/resource/newChannel.png",
        Action_New_CollectChannel, true);
    m_menuCollectChannel->addAction(actNewChannel);
    connect(m_projectTreeWidget, &QProjectTreeWidget::customContextMenuRequested,
        this, &MainWindow::customContextMenuRequested);
    // connect(m_projectTreeWidget,&QProjectTreeWidget::clicked,this,&MainWindow::tree_clicked);
    connect(m_projectTreeWidget, &QProjectTreeWidget::currentItemChanged, this,
        &MainWindow::tree_clicked);
    //新建采集设备
    m_menuCollectDevice = new QMenu();
    QAction* actNewCollectDev = createAction(
        "新建设备", ":/resource/newChannel.png", Action_New_CollectDevice, true);
    QAction* actDelCollectChannel = createAction(
        "删除通道", ":/resource/newChannel.png", Action_Del_CollectChannel, true);
    m_menuCollectDevice->addAction(actNewCollectDev);
    m_menuCollectDevice->addAction(actDelCollectChannel);
    //采集设备的删除，以及复制菜单
    m_menuCollectDeleteCp = new QMenu();
    QAction* actDelCollectDev = createAction(
        "删除设备", ":/resource/newChannel.png", Action_Del_CollectDevice, true);
    QAction* actCopyCollectDev = createAction(
        "复制设备", ":/resource/newChannel.png", Action_Cpy_CollectDevice, true);
    m_menuCollectDeleteCp->addAction(actDelCollectDev);
    m_menuCollectDeleteCp->addAction(actCopyCollectDev);
    //新建上传通道
    m_menuUpdateChannel = new QMenu();
    QAction* actNewUpdateChannel = createAction("新建转发通道", ":/resource/newChannel.png",
        Action_New_UpdateChannel, true);
    m_menuUpdateChannel->addAction(actNewUpdateChannel);
    //上传通道，删除与复制
    m_menuUpdateOperate = new QMenu();
    QAction* actDelUpdateChannel = createAction("删除转发通道", ":/resource/newChannel.png",
        Action_Del_UpdateChannel, true);
    QAction* actCpUpdateChannel = createAction("复制转发通道", ":/resource/newChannel.png",
        Action_Cpy_UpdateChannel, true);
    m_menuUpdateOperate->addAction(actDelUpdateChannel);
    m_menuUpdateOperate->addAction(actCpUpdateChannel);
    // ribbonBar样式
    ribbonBar()->setRibbonStyle(SARibbonBar::RibbonStyleCompactThreeRow);
    QTimer::singleShot(0, this, [this]() {
        this->setRibbonTheme(SARibbonTheme::RibbonThemeOffice2016Blue);
    });
    ribbonBar()->setTitleBarHeight(30);
    ribbonBar()->setEnableWordWrap(false);
    ribbonBar()->setCategoryHeight(75);
    ribbonBar()->categoryPages().at(0)->setStyleSheet(
        "background-color:#e3edf9; ");

    //打开最近一次工程
    QStringList fileList = GetLastOpenListFile();
    if (fileList.size() > 0)
        m_projectTreeWidget->InitOpenProject(fileList.at(0));
}

MainWindow::~MainWindow() { delete ui; }

void MainWindow::initApplicationMenu()
{
    //系统菜单
    ribbonBar()->applicationButton()->setText(
        ("  &系统  ")); // 文字两边留有间距，好看一点
    if (!mMenuApplicationBtn) {
        mMenuApplicationBtn = new SARibbonMenu(this);
        m_lastOpenAction = new QAction("最近工程");
        m_lastOpenAction->setIcon(QIcon(":/resource/exit.png"));
        //创建子菜单
        QStringList fileList = GetLastOpenListFile();
        m_menuOpenProjectChild = new QMenu();
        for (QString item : fileList) {
            QAction* newAction = new QAction(m_lastOpenAction);
            newAction->setText(item);
            m_menuOpenProjectChild->addAction(newAction);
        }
        m_lastOpenAction->setMenu(m_menuOpenProjectChild);

        mMenuApplicationBtn->addAction(
            createAction("帮助系统", ":/resource/exit.png", Action_System_Help));
        mMenuApplicationBtn->addAction(m_lastOpenAction);
        // mMenuApplicationBtn->addAction(createAction("退出程序",
        // ":/resource/exit.png",Action_System_Close));
    }
    SARibbonApplicationButton* appBtn = qobject_cast<SARibbonApplicationButton*>(
        ribbonBar()->applicationButton());
    if (!appBtn) {
        return;
    }
    appBtn->setMenu(mMenuApplicationBtn);
}

QAction* MainWindow::createAction(const QString& text, const QString& iconurl,
    QActionUserType userData, bool connectSlot)
{
    QAction* act = new QAction(this);
    act->setText(text);
    act->setIcon(QIcon(iconurl));
    act->setObjectName(text);
    act->setData(userData);
    if (connectSlot)
        connect(act, &QAction::triggered, this,
            &MainWindow::slot_on_actionTriggered);
    return act;
}

void MainWindow::initToolboorProject()
{
    SARibbonCategory* categoryOther = new SARibbonCategory();
    categoryOther->setCategoryName(tr("&工程管理"));
    categoryOther->setObjectName("categoryProject");
    SARibbonPannel* pannel1 = categoryOther->addPannel(tr("操作"));
    QAction* actNewProject = createAction(tr("新建工程"), (":/resource/new.svg"), Action_New_Project);
    QAction* actOpenProject = createAction(
        tr("打开工程"), (":/resource/open.png"), Action_Open_Project);
    QAction* actSaveProject = createAction(
        tr("保存工程"), (":/resource/SAVE.png"), Action_Save_Project);
    QAction* actModiProject = createAction(
        tr("另存工程"), (":/resource/modi.png"), Action_SaveAS_Project);
    QAction* actDelProject = createAction(
        tr("删除工程"), (":/resource/delete.png"), Action_Delete_Project);
    QAction* actViewProject = createAction(
        tr("浏览工程"), (":/resource/delete.png"), Action_View_Project);
    m_menuProject->addAction(actNewProject);
    m_menuProject->addAction(actOpenProject);
    m_menuProject->addAction(actSaveProject);
    m_menuProject->addAction(actModiProject);
    m_menuProject->addAction(actDelProject);
    m_menuProject->addAction(actViewProject);
    pannel1->addAction(actNewProject, QToolButton::DelayedPopup);
    pannel1->addAction(actOpenProject, QToolButton::DelayedPopup);
    pannel1->addAction(actSaveProject, QToolButton::DelayedPopup);
    pannel1->addAction(actModiProject, QToolButton::DelayedPopup);
    pannel1->addAction(actDelProject, QToolButton::DelayedPopup);
    pannel1->addAction(actViewProject, QToolButton::DelayedPopup);

    SARibbonPannel* pannel2 = categoryOther->addPannel(tr("工具"));
    QAction* actUpdaateProject = createAction(
        tr("上传工程"), (":/resource/new.svg"), Action_Upload_Project, true);
    QAction* actDownProject = createAction(tr("下载工程"), (":/resource/new.svg"),
        Action_Down_Project, true);
    QAction* actRTBase = createAction(tr("实时库"), (":/resource/new.svg"),
        ACtion_View_RTBase, true);
    pannel2->addAction(actUpdaateProject, QToolButton::DelayedPopup);
    pannel2->addAction(actDownProject, QToolButton::DelayedPopup);
    pannel2->addAction(actRTBase, QToolButton::DelayedPopup);
    ribbonBar()->addCategoryPage(categoryOther);

    for (QAction* item : m_menuProject->actions()) {
        connect(item, &QAction::triggered, this,
            &MainWindow::slot_on_actionTriggered);
    }
    //    SARibbonCategory* toolCategory = new SARibbonCategory();
    //    toolCategory->setObjectName("categoryProject");
    //    toolCategory->setCategoryName("工具");
}

//菜单点击事件
void MainWindow::slot_on_actionTriggered()
{
    QAction* currentAction = qobject_cast<QAction*>(sender());
    int actionType = currentAction->data().toInt();
    if (actionType == Action_New_Project) //新建工程
    {
        NewProjectDialog newProject;
        if (QDialog::Accepted == newProject.exec()) {
            ModelXml::GetInstance()->CloseProject();
            stProject projInfo = newProject.GetProjectInfo();
            m_projectTreeWidget->AddProject(projInfo);
        }
    } else if (Action_Open_Project == actionType) //打开工程
    {
        QString pathFile = QFileDialog::getOpenFileName(
            nullptr, "选择工程文件", QDir::currentPath(), "PXM(*.pxm);;*.*(*.*)");
        if (!pathFile.isNull()) {

            if (m_projectTreeWidget->InitOpenProject(pathFile)) {
                ModelXml::GetInstance()->GetProject().path = pathFile.mid(0, pathFile.lastIndexOf('/')).toStdString();
                wirteLastOpenFile((ModelXml::GetInstance()->GetProject().path + "/" + ModelXml::GetInstance()->GetProject().name + ".pxm").c_str());
            } else {
                QMessageBox::information(nullptr, "打开工程文件", "打开工程文件失败");
            }
        }
    } else if (Action_Save_Project == actionType) //保存工程
    {
        ModelXml::GetInstance()->GetProject().modiTime = QDateTime::currentDateTime()
                                                             .toString("yyyy-MM-dd hh:mm:ss")
                                                             .toStdString();
        if (ModelXml::GetInstance()->SaveXml()) {
            wirteLastOpenFile((ModelXml::GetInstance()->GetProject().path + "/" + ModelXml::GetInstance()->GetProject().name + ".pxm")
                                  .c_str());
            QMessageBox::information(nullptr, "保存工程", "保存工程成功");
        } else {
            QMessageBox::information(nullptr, "保存工程", "保存工程失败");
        }
    } else if (Action_SaveAS_Project == actionType) //另存为工程
    {
        QString pathFile = QFileDialog::getExistingDirectory(
            nullptr, "选择工程路径", QDir::currentPath());
        if (!pathFile.isNull() && !pathFile.isNull()) {
            ModelXml::GetInstance()->GetProject().path = pathFile.toStdString();
            if (ModelXml::GetInstance()->SaveXml()) {
                wirteLastOpenFile(pathFile);
                QMessageBox::information(nullptr, "保存工程", "保存工程成功");
            } else {
                QMessageBox::information(nullptr, "保存工程", "保存工程失败");
            }
        }

    } else if (Action_Delete_Project == actionType) { //删除工程
        if (QMessageBox::information(nullptr, "删除工程",
                "是否确认删除该工程",
                QMessageBox::Yes | QMessageBox::No,
                QMessageBox::Yes)
            == QMessageBox::No)
            return;
        m_projectTreeWidget->DeleteProject();
    } else if (actionType == Action_New_CollectChannel) //新建采集通道
    {
        NewCollectChannelDialog newChannel;
        int code = m_projectTreeWidget->GetCollectChannelMaxID() + 1;
        newChannel.SetInitChannelName("C" + QString::number(code));
        if (QDialog::Accepted == newChannel.exec()) {
            stCollectChannel channel = newChannel.getChannel();
            channel.id = code;
            m_projectTreeWidget->AddCollectChannel(channel);
        }
    } else if (actionType == Action_New_CollectDevice) //新建采集设备
    {
        int parentID = m_projectTreeWidget->currentItem()->data(1, Qt::UserRole).toInt();
        int id = ModelXml::GetInstance()->GetMaxCollectDeviceID(parentID);
        int deviceID = id + 1;

        stCollecDevice device;
        NewDeviceDialog newDevice;
        newDevice.SetInitDevicelName("D" + QString::number(deviceID), parentID);
        if (newDevice.exec() == QDialog::Accepted) {
            device = newDevice.GetDeviceInfo();
            device.id = deviceID;
            m_projectTreeWidget->AddCollectDevice(parentID, device);
            qDebug() << "channel id = " << parentID;
        }
    } else if (actionType == Action_Cpy_CollectDevice) //复制采集设备
    {
        CommInputDialog commInputDialog;
        commInputDialog.SetPrompt("请输入设备名称");
        QTreeWidgetItem* item = m_projectTreeWidget->currentItem();
        int channelID = item->parent()->data(1, Qt::UserRole).toInt();
        int devID = item->data(1, Qt::UserRole).toInt();
        int idMax = ModelXml::GetInstance()->GetMaxCollectDeviceID(channelID) + 1;
        commInputDialog.SetDefalutValue("D" + QString::number(idMax));
        if (commInputDialog.exec() == CommInputDialog::Accepted) {
            QString name = commInputDialog.GetInputText();
            stCollecDevice devInfo = ModelXml::GetInstance()->GetCollectDevice(channelID, devID);
            devInfo.id = idMax;
            devInfo.name = name.toStdString();
            m_projectTreeWidget->AddCollectDevice(channelID, devInfo);
        }
    } else if (actionType == Action_Del_CollectChannel) //删除采集通道
    {
        if (QMessageBox::information(nullptr, "删除采集通道",
                "是否确认删除该采集通道",
                QMessageBox::Yes | QMessageBox::No,
                QMessageBox::Yes)
            == QMessageBox::No)
            return;
        int channelID = m_projectTreeWidget->currentItem()->data(1, Qt::UserRole).toInt();
        m_projectTreeWidget->DelCollectChannel(channelID);
    } else if (actionType == Action_Del_CollectDevice) //删除采集设备
    {
        if (QMessageBox::information(nullptr, "删除采集设备",
                "是否确认删除该采集设备",
                QMessageBox::Yes | QMessageBox::No,
                QMessageBox::Yes)
            == QMessageBox::No)
            return;
        int devID = m_projectTreeWidget->currentItem()->data(1, Qt::UserRole).toInt();
        m_projectTreeWidget->DelCollectDevice(m_projectTreeWidget->currentItem()
                                                  ->parent()
                                                  ->data(1, Qt::UserRole)
                                                  .toInt(),
            devID);
    } else if (actionType == Action_Del_UpdateChannel) //删除转发通道
    {
        if (QMessageBox::information(nullptr, "删除转发通道",
                "是否确认删除该转发通道",
                QMessageBox::Yes | QMessageBox::No,
                QMessageBox::Yes)
            == QMessageBox::No)
            return;

        int channelID = m_projectTreeWidget->currentItem()->data(1, Qt::UserRole).toInt();
        m_projectTreeWidget->DelUpdateChannel(channelID);
    } else if (actionType == Action_Cpy_UpdateChannel) //复制转发通道
    {
        CommInputDialog commInputDialog;
        commInputDialog.SetPrompt("请输入转发通道名称");
        QTreeWidgetItem* item = m_projectTreeWidget->currentItem();
        int updataChannelID = item->data(1, Qt::UserRole).toInt();
        int idMax = ModelXml::GetInstance()->GetMaxUpdateChannelID() + 1;
        commInputDialog.SetDefalutValue("T" + QString::number(idMax));
        if (commInputDialog.exec() == CommInputDialog::Accepted) {
            QString name = commInputDialog.GetInputText();
            stUpdateChannel updateInfo = ModelXml::GetInstance()->GetUpdateChannelInfo(updataChannelID);
            updateInfo.id = idMax;
            updateInfo.name = name.toStdString();
            m_projectTreeWidget->AddUpdateChannel(updateInfo);
        }
    } else if (Action_New_UpdateChannel == actionType) //新建上传通道
    {
        NewUpdateChannelDialog updateDialog;
        stUpdateChannel updateChannel;
        int updateID = ModelXml::GetInstance()->GetMaxUpdateChannelID() + 1;
        updateDialog.SetInitChannelName("T" + QString::number(updateID));
        if (updateDialog.exec() == QDialog::Accepted) {
            updateChannel = updateDialog.GetUpdateChannelInfo();
            updateChannel.id = updateID;
            m_projectTreeWidget->AddUpdateChannel(updateChannel);
        }
    } else if (Action_Upload_Project == actionType) //新建上传通道
    {
        UploadProjectDialog uploadDialog;
        uploadDialog.exec();
    } else if (Action_Down_Project == actionType) //下载工程
    {
        DownLoadDialog downloadDialog;
        downloadDialog.exec();
    }
}
//弹出菜单
void MainWindow::customContextMenuRequested(const QPoint& pos)
{
    // QTreeWidget* curTree = qobject_cast<QTreeWidget*>(sender());
    // 根据具体的坐标可以求出当前右键点击的是哪一个Item，然后做出对应的处理
    QTreeWidgetItem* item = m_projectTreeWidget->currentItem();
    if (item == nullptr) {
        m_menuProject->popup(QCursor::pos());
    } else {
        int userData = item->data(0, Qt::UserRole).toInt();
        if (userData == QProjectTreeWidget::Node_Project) //新建工程
        {
            m_menuProject->actions().at(0)->setDisabled(true);
            m_menuProject->popup(QCursor::pos());
        } else if (userData == QProjectTreeWidget::Node_CollectChannel) //新建通道
        {
            m_menuCollectChannel->popup(QCursor::pos());
        } else if (userData == QProjectTreeWidget::Node_CollectChannelArray) {
            m_menuCollectDevice->popup(QCursor::pos());
        } else if (userData == QProjectTreeWidget::Node_CollectDev) {
            m_menuCollectDeleteCp->popup(QCursor::pos());
        } else if (userData == QProjectTreeWidget::Node_UpdateChannel) {
            m_menuUpdateChannel->popup(QCursor::pos());
        } else if (userData == QProjectTreeWidget::Node_UpdateChannelDEV) {
            m_menuUpdateOperate->popup(QCursor::pos());
        }
    }
}

void MainWindow::changeAttrobPage(QWidget* currentWidget)
{
    QLayoutItem* item = ui->formLayout->itemAt(0);
    if (item) {
        QWidget* pWidget = item->widget();
        ui->formLayout->removeWidget(pWidget);
        pWidget->hide();
    }
    if (currentWidget) {
        ui->formLayout->addWidget(currentWidget);
        currentWidget->show();
    }
}

// TREE左键点击事件
void MainWindow::tree_clicked(QTreeWidgetItem* current,
    QTreeWidgetItem* previous)
{
    QTreeWidgetItem* item = m_projectTreeWidget->currentItem();

    if (item == nullptr) {
        m_menuProject->actions().at(0)->setEnabled(true);
        m_menuProject->popup(QCursor::pos());
    } else {
        int userData = item->data(0, Qt::UserRole).toInt();
        if (userData == QProjectTreeWidget::Node_Project) //工程属性
        {
            m_projectAttribForm->InitUiData();
            changeAttrobPage(m_projectAttribForm);
        } else if (userData == QProjectTreeWidget::Node_CollectChannel) //采集通道统计
        {
            m_collectCountForm->InitUiData();
            changeAttrobPage(m_collectCountForm);
        } else if (userData == QProjectTreeWidget::Node_CollectChannelArray) //采集通道属性
        {
            int userData2 = item->data(1, Qt::UserRole).toInt();
            m_collectChannelForm->SetChannelID(userData2);
            m_collectChannelForm->SetCurrentTreeItem(item);
            m_collectChannelForm->ShowWindow();
            changeAttrobPage(m_collectChannelForm);
        } else if (userData == QProjectTreeWidget::Node_CollectDev) //采集设备属性
        {
            int channelID = item->parent()->data(1, Qt::UserRole).toInt();
            int deviceID = item->data(1, Qt::UserRole).toInt();

            QString protoName = ModelXml::GetInstance()->GetCollectChannel(channelID).protoName.c_str();
            m_collectDeviceForm->SetProtoName(protoName);
            m_collectDeviceForm->SetDeviceID(deviceID);
            m_collectDeviceForm->SetChannelID(channelID);
            m_collectDeviceForm->SetCurrentTreeItem(item);
            m_collectDeviceForm->ShowWindow();
            changeAttrobPage(m_collectDeviceForm);
        } else if (userData == QProjectTreeWidget::Node_UpdateChannel) //转发通道统计
        {
            m_updateCountForm->InitUiData();
            changeAttrobPage(m_updateCountForm);
        } else if (userData == QProjectTreeWidget::Node_UpdateChannelDEV) //转发通道属性
        {
            int chanelID = item->data(1, Qt::UserRole).toInt();
            m_updateChannelForm->SetChannelID(chanelID);
            m_updateChannelForm->SetCurrentTreeItem(item);
            m_updateChannelForm->ShowWindow();
            changeAttrobPage(m_updateChannelForm);
        }
    }
}

QStringList MainWindow::GetLastOpenListFile()
{
    QStringList resList;
    pugi::xml_document doc;
    QString configFile = QDir::currentPath() + "/lastProject.xml";
    if (doc.load_file(configFile.toStdString().c_str())) {
        xml_node history_node = doc.root().child("history");
        xml_node file_node = history_node.first_child();
        while (file_node) {
            resList.push_back(file_node.attribute("name").value());
            file_node = file_node.next_sibling();
        }
    }
    return resList;
}

bool MainWindow::wirteLastOpenFile(QString fileName)
{
    pugi::xml_document doc;
    QString configFile = QDir::currentPath() + "/lastProject.xml";
    if (!doc.load_file(
            configFile.toStdString().c_str())) //如果不存在，则创建该文件
    {
        pugi::xml_node declaration = doc.prepend_child(pugi::node_declaration);
        declaration.append_attribute("version") = "1.0";
        declaration.append_attribute("encoding") = "UTF-8";

        xml_node history_node = doc.append_child("history");
        xml_node file_node = history_node.append_child("file");
        file_node.append_attribute("name") = fileName.toStdString().c_str();
        return doc.save_file(configFile.toStdString().c_str()); // xml_encoding::encoding_utf8);
    }
    xml_node history_node = doc.root().child("history");
    xml_node find_node = history_node.find_child_by_attribute("file", "name", fileName.toStdString().c_str());
    if (!find_node.empty())
        history_node.remove_child(find_node);
    int countFile = history_node.children_num("file");
    if (countFile > 5) {
        xml_node last_node = history_node.last_child();
        history_node.remove_child(last_node);
        xml_node first_node = history_node.first_child();
        xml_node new_node = history_node.insert_child_before("file", first_node);
        new_node.append_attribute("name") = fileName.toStdString().c_str();
    } else if (countFile > 0) {
        xml_node first_node = history_node.first_child();
        xml_node new_node = history_node.insert_child_before("file", first_node);
        new_node.append_attribute("name") = fileName.toStdString().c_str();
    } else {
        xml_node new_node = history_node.append_child("file");
        new_node.append_attribute("name") = fileName.toStdString().c_str();
    }
    return doc.save_file(configFile.toStdString().c_str()); // xml_encoding::encoding_utf8);
}
